﻿using Abp.Domain.Repositories;
using Camc.Quality.Bop;
using Camc.Quality.Common.CommonDate;
using Camc.Quality.DataCenter.AssemblyProgressBoard;
using Camc.Quality.ProductionPlan;
using Camc.Quality.Quality;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Camc.Quality.DataCenter.AssemblyProgressBoard.TaskBoardList;
using static Camc.Quality.DataCenter.AssemblyProgressBoard.TaskBoardListBTList;

namespace Camc.Quality.DataCenter
{
    public class AssemblyProgressBoardAppService : QualityAppServiceBase
    {
        private readonly IRepository<MakeTask, Guid> _makeTaskRepository;
        private readonly IRepository<BopNode, Guid> _bopNodeRepository;
        private readonly IRepository<BopDesc, Guid> _bopDescRepository;
        private readonly IRepository<WorkStepEntity, Guid> _workStepEntityRepository;
        private readonly IRepository<ProductionScheduler, Guid> _productionSchedulerRepository;
        private readonly IRepository<ProcessesEntity, Guid> _processesEntityRepository;
        private readonly IRepository<TechniqueEntity, Guid> _techniqueEntityRepository;
        public AssemblyProgressBoardAppService(
            IRepository<MakeTask, Guid> makeTaskRepository,
            IRepository<BopNode, Guid> bopNodeRepository,
            IRepository<BopDesc, Guid> bopDescRepository,
            IRepository<WorkStepEntity, Guid> workStepEntityRepository,
            IRepository<ProductionScheduler, Guid> productionSchedulerRepository,
            IRepository<ProcessesEntity, Guid> processesEntityRepository,
            IRepository<TechniqueEntity, Guid> techniqueEntityRepository
            )
        {
            _makeTaskRepository = makeTaskRepository;
            _bopNodeRepository = bopNodeRepository;
            _bopDescRepository = bopDescRepository;
            _productionSchedulerRepository = productionSchedulerRepository;
            _workStepEntityRepository = workStepEntityRepository;
            _processesEntityRepository = processesEntityRepository;
            _techniqueEntityRepository = techniqueEntityRepository;
        }
        /// <summary>
        /// 芯级任务数据查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TaskBoardList GetNodeDropListOfTask(Guid id)
        {
            TaskBoardList taskBoardList = new TaskBoardList();
            List<TaskBoardListXJList> taskBoardListXJLists = new List<TaskBoardListXJList>();
            var bopDesc = _bopDescRepository.FirstOrDefault(s => s.Id == id);
            if (bopDesc != null)
            {
                //获取所有芯级
                var query = (from xjnode in _bopNodeRepository.GetAll().Where(s => s.ParentId == id)
                             join desc in _bopDescRepository.GetAll()
                             on xjnode.ParentId equals desc.Id
                             select new
                             {
                                 Id = xjnode.Id,
                                 Name = xjnode.NodeName,
                                 NodeCode = xjnode.NodeCode
                             }).ToList();
                int u = 0;
                var xJNode = query.OrderBy(ee =>
                {
                    u = Array.IndexOf(new string[]
                    {
                        "芯一级",
                        "芯二级",
                        "芯三级",
                        "星罩",
                        "助推Ⅰ",
                        "助推Ⅱ",
                        "助推Ⅲ",
                        "助推Ⅳ"
                    }, ee.Name);
                    if (u != -1) { return u; }
                    else { return int.MaxValue; }
                });
                if (bopDesc.WorkingHourStatus == "0")//工序任务
                {
                    foreach (var item in xJNode)
                    {
                        TaskBoardListXJList taskBoardListXJList = new TaskBoardListXJList();
                        var node = _bopNodeRepository.GetAll().Where(d => d.BopDescId == bopDesc.Id && d.NodeCode.StartsWith(item.NodeCode) && d.TechniqueEntityId != null).ToList();
                        if (node.Count > 0)
                        {
                            var techList = node.Select(d => d.TechniqueEntityId);

                            var processes = from cc in _processesEntityRepository.GetAll()
                                            join mm in techList on cc.TechniqueEntityId equals mm
                                            select new StatisticsHour
                                            {
                                                Id = cc.Id,
                                                Hour = cc.ProcessesWorking,
                                            };
                            if (processes.Count() > 0)
                            {
                                var proFinish = (from cc in processes
                                                 join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                                 where mm.ProductingStatus == ProductingStatus.已完成
                                                 select new StatisticsHour
                                                 {
                                                     Id = cc.Id,
                                                     Hour = cc.Hour,
                                                 }).ToList();
                                var finishIds = proFinish.Select(d => d.Id);
                                var processesIds = processes.Select(d => d.Id);
                                var leftIds = processesIds.Except(finishIds).ToArray();

                                for (int i = 0; i < leftIds.Length; i++)
                                {
                                    var workList = from cc in _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == leftIds[i])
                                                   select new
                                                   {
                                                       Id = cc.Id,
                                                   };
                                    var workFinish = from cc in workList
                                                     join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                                     where mm.ProductingStatus == ProductingStatus.已完成
                                                     select cc;
                                    var workCount = workList.Count();
                                    var workFinishCount = workFinish.Count();
                                    if (workCount == workFinishCount)
                                    {
                                        var tempHour = processes.Where(d => d.Id == leftIds[i]).First().Hour;
                                        StatisticsHour hour = new StatisticsHour();
                                        hour.Id = leftIds[i];
                                        hour.Hour = tempHour;
                                        proFinish.Add(hour);
                                    }
                                }
                                //完成数量
                                taskBoardListXJList.CompleteCount = proFinish.Count();
                                //任务数量
                                taskBoardListXJList.TaskCount = Convert.ToDecimal(processes.Count());
                                //任务数量百分比
                                if (taskBoardList.TaskCount == 0) taskBoardList.StepCompletionSchedule = 0;
                                else taskBoardList.StepCompletionSchedule = decimal.Round(taskBoardList.CompleteCount* 100 / taskBoardList.TaskCount);
                                //完成工时
                                taskBoardListXJList.CompleteHour = proFinish.Sum(d => d.Hour);
                                //任务工时
                                taskBoardListXJList.TaskHour = processes.Sum(d => d.Hour);
                                //任务工时百分比
                                if (taskBoardList.TaskHour == 0) taskBoardList.HourCompletionSchedule = 0;
                                else taskBoardList.HourCompletionSchedule = decimal.Round(taskBoardList.CompleteHour*100 / taskBoardList.TaskHour, 2);
                            }
                            else
                            {
                                //完成数量
                                taskBoardListXJList.CompleteCount = 0;
                                //任务数量
                                taskBoardListXJList.TaskCount = (decimal)processes.Count();
                                //任务数量百分比
                                taskBoardListXJList.StepCompletionSchedule = 0;
                                //完成工时
                                taskBoardListXJList.CompleteHour = 0;
                                //任务工时
                                taskBoardListXJList.TaskHour = (decimal)processes.Sum(d => d.Hour);
                                //任务工时百分比
                                taskBoardListXJList.HourCompletionSchedule = 0;

                            }
                        }
                        else
                        {
                            //完成数量
                            taskBoardListXJList.CompleteCount = 0;
                            //任务数量
                            taskBoardListXJList.TaskCount = 0;
                            //任务数量百分比
                            taskBoardListXJList.StepCompletionSchedule = 0;
                            //完成工时
                            taskBoardListXJList.CompleteHour = 0;
                            //任务工时
                            taskBoardListXJList.TaskHour = 0;
                            //任务工时百分比
                            taskBoardListXJList.HourCompletionSchedule = 0;
                        }
                        //芯级名称
                        taskBoardListXJList.Name = item.Name;
                        taskBoardListXJLists.Add(taskBoardListXJList);
                    }
                }
                else if (bopDesc.WorkingHourStatus == "1")//工步任务
                {
                    foreach (var item in xJNode)
                    {
                        TaskBoardListXJList taskBoardListXJList = new TaskBoardListXJList();
                        var node = _bopNodeRepository.GetAll().Where(d => d.BopDescId == bopDesc.Id && d.NodeCode.StartsWith(item.NodeCode) && d.TechniqueEntityId != null).ToList();
                        if (node.Count > 0)
                        {
                            List<StatisticsHour> hours = new List<StatisticsHour>();
                            var techList = node.Select(d => d.TechniqueEntityId);

                            var totalWork = from cc in _workStepEntityRepository.GetAll()
                                            join mm in techList on cc.TechniqueEntityId equals mm
                                            select new StatisticsHour { Id = cc.Id, Hour = cc.WorkStepWorking };
                            var workSteps = (from cc in _processesEntityRepository.GetAll()
                                             join mm in techList on cc.TechniqueEntityId equals mm
                                             join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                             join pp in _workStepEntityRepository.GetAll() on cc.Id equals pp.ProcessesEntityId
                                             where ff.ProductingStatus == ProductingStatus.已完成
                                             select new StatisticsHour { Id = pp.Id, Hour = pp.WorkStepWorking }).ToList();
                            var workFinish = (from cc in totalWork
                                              join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                              where ff.ProductingStatus == ProductingStatus.已完成
                                              select new StatisticsHour { Id = cc.Id, Hour = cc.Hour }).ToList();
                            if (workSteps.Count > 0)
                            {
                                hours.AddRange(workSteps);
                            }
                            if (workFinish.Count > 0)
                            {
                                hours.AddRange(workFinish);
                            }

                            if (hours.Count() > 0)
                            {
                                //完成数量
                                taskBoardListXJList.CompleteCount = hours.Count;
                                //任务数量
                                taskBoardListXJList.TaskCount = totalWork.Count();
                                //任务数量百分比
                                taskBoardListXJList.StepCompletionSchedule = decimal.Round(taskBoardListXJList.CompleteCount * 100 / taskBoardListXJList.TaskCount);
                                //完成工时
                                taskBoardListXJList.CompleteHour = hours.Sum(d => d.Hour);
                                //任务工时
                                taskBoardListXJList.TaskHour = totalWork.Sum(d => d.Hour);
                                //任务工时百分比
                                taskBoardListXJList.HourCompletionSchedule = decimal.Round(taskBoardListXJList.CompleteHour * 100 / taskBoardListXJList.TaskHour);
                            }
                            else
                            {
                                //完成数量
                                taskBoardListXJList.CompleteCount = 0;
                                //任务数量
                                taskBoardListXJList.TaskCount = totalWork.Count();
                                //任务数量百分比
                                taskBoardListXJList.StepCompletionSchedule = 0;
                                //完成工时
                                taskBoardListXJList.CompleteHour = 0;
                                //任务工时
                                taskBoardListXJList.TaskHour = totalWork.Sum(d => d.Hour);
                                //任务工时百分比
                                taskBoardListXJList.HourCompletionSchedule = 0;
                            }
                        }
                        else
                        {
                            //完成数量
                            taskBoardListXJList.CompleteCount = 0;
                            //任务数量
                            taskBoardListXJList.TaskCount = 0;
                            //任务数量百分比
                            taskBoardListXJList.StepCompletionSchedule = 0;
                            //完成工时
                            taskBoardListXJList.CompleteHour = 0;
                            //任务工时
                            taskBoardListXJList.TaskHour = 0;
                            //任务工时百分比
                            taskBoardListXJList.HourCompletionSchedule = 0;
                        }
                        //芯级名称
                        taskBoardListXJList.Id = item.Id;
                        taskBoardListXJList.Name = item.Name;
                        taskBoardListXJLists.Add(taskBoardListXJList);
                    }
                }
                //完成数量
                taskBoardList.CompleteCount = taskBoardListXJLists.Select(s => s.CompleteCount).Sum();
                //任务数量
                taskBoardList.TaskCount = taskBoardListXJLists.Select(s => s.TaskCount).Sum();
                //任务数量百分比
                if (taskBoardList.TaskCount == 0) taskBoardList.StepCompletionSchedule = 0;
                else taskBoardList.StepCompletionSchedule = decimal.Round(taskBoardList.CompleteCount * 100 / taskBoardList.TaskCount);
                //完成工时
                taskBoardList.CompleteHour = taskBoardListXJLists.Select(s => s.CompleteHour).Sum();
                //任务工时
                taskBoardList.TaskHour = taskBoardListXJLists.Select(s => s.TaskHour).Sum();
                //任务工时百分比
                if (taskBoardList.TaskHour == 0) taskBoardList.HourCompletionSchedule = 0;
                else taskBoardList.HourCompletionSchedule = decimal.Round(taskBoardList.CompleteHour * 100 / taskBoardList.TaskHour);
                taskBoardList.TaskBoardListXJLists = taskBoardListXJLists;
            }
            return taskBoardList;
        }
        /// <summary>
        /// 根据芯级获取部套下拉列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public List<LabelCollection> GetBTDropList(Guid id)
        {
            var query = (from btnode in _bopNodeRepository.GetAll().Where(s => s.ParentId == id)
                         select new LabelCollection
                         {
                             Label = btnode.NodeName,
                             Value = btnode.Id
                         }).ToList();
            if (query.Count() > 0)
            {
                return query.ToList();
            }
            return new List<LabelCollection>();
        }
        /// <summary>
        /// 部套数据查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TaskBoardListBTList GetBTTaskListForBoard(Guid xjid, Guid? btid)
        {
            if (xjid == Guid.Empty) return new TaskBoardListBTList();
            if (btid == Guid.Empty || btid == null)
            {
                btid = _bopNodeRepository.GetAll().First(s => s.ParentId == xjid).Id;
            }
            TaskBoardListBTList taskBoardListBTList = new TaskBoardListBTList();
            List<TechniqueEntityData> techniqueEntityDatas = new List<TechniqueEntityData>();
            var bTnode = _bopNodeRepository.FirstOrDefault(s => s.Id == btid);
            var bopDesc = _bopDescRepository.FirstOrDefault(s => s.Id == bTnode.BopDescId);
            if (bopDesc != null)
            {
                //获取部套下所有工艺规程
                var node = _bopNodeRepository.GetAll().Where(d => d.BopDescId == bopDesc.Id && d.NodeCode.StartsWith(bTnode.NodeCode) && d.TechniqueEntityId != null).ToList();
                if (node.Count > 0)
                {
                    if (bopDesc.WorkingHourStatus == "0")//工序任务
                    {
                        foreach (var item in node)
                        {
                            TechniqueEntityData techniqueEntityData = new TechniqueEntityData();
                            var tech = _techniqueEntityRepository.FirstOrDefault(s => s.Id == item.TechniqueEntityId);
                            var processes = from cc in _processesEntityRepository.GetAll()
                                            where cc.TechniqueEntityId == tech.Id
                                            select new StatisticsHour
                                            {
                                                Id = cc.Id,
                                                Hour = cc.ProcessesWorking,
                                            };
                            if (processes.Count() > 0)
                            {
                                var proFinish = (from cc in processes
                                                 join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                                 where mm.ProductingStatus == ProductingStatus.已完成
                                                 select new StatisticsHour
                                                 {
                                                     Id = cc.Id,
                                                     Hour = cc.Hour,
                                                 }).ToList();
                                var finishIds = proFinish.Select(d => d.Id);
                                var processesIds = processes.Select(d => d.Id);
                                var leftIds = processesIds.Except(finishIds).ToArray();

                                for (int i = 0; i < leftIds.Length; i++)
                                {
                                    var workList = from cc in _workStepEntityRepository.GetAll().Where(d => d.ProcessesEntityId == leftIds[i])
                                                   select new
                                                   {
                                                       Id = cc.Id,
                                                   };
                                    var workFinish = from cc in workList
                                                     join mm in _productionSchedulerRepository.GetAll() on cc.Id equals mm.NodeId
                                                     where mm.ProductingStatus == ProductingStatus.已完成
                                                     select cc;
                                    var workCount = workList.Count();
                                    var workFinishCount = workFinish.Count();
                                    if (workCount == workFinishCount)
                                    {
                                        var tempHour = processes.Where(d => d.Id == leftIds[i]).First().Hour;
                                        StatisticsHour hour = new StatisticsHour();
                                        hour.Id = leftIds[i];
                                        hour.Hour = tempHour;
                                        proFinish.Add(hour);
                                    }
                                }
                                //完成数量
                                techniqueEntityData.CompleteCount = proFinish.Count();
                                //任务数量
                                techniqueEntityData.TaskCount = processes.Count();
                                //完成工时
                                techniqueEntityData.CompleteHour = (int)proFinish.Sum(d => d.Hour);
                                //任务工时
                                techniqueEntityData.TaskHour = (int)processes.Sum(d => d.Hour);
                            }
                            else
                            {
                                //完成数量
                                techniqueEntityData.CompleteCount = 0;
                                //任务数量
                                techniqueEntityData.TaskCount = processes.Count();
                                //完成工时
                                techniqueEntityData.CompleteHour = 0;
                                //任务工时
                                techniqueEntityData.TaskHour = (int)processes.Sum(d => d.Hour);
                            }
                            //规程图号
                            techniqueEntityData.DrawingNo = tech.TechniqueNumber;
                            //规程名称
                            techniqueEntityData.Name = tech.TechniqueName;
                            //状态
                            if (techniqueEntityData.TaskCount == techniqueEntityData.CompleteCount && techniqueEntityData.TaskCount > 0)
                            {
                                techniqueEntityData.State = "已完成";
                            }
                            if (techniqueEntityData.TaskCount > techniqueEntityData.CompleteCount && techniqueEntityData.TaskCount > 0)
                            {
                                techniqueEntityData.State = "生产中";
                            }
                            if (techniqueEntityData.TaskCount == 0)
                            {
                                techniqueEntityData.State = "未生产";
                            }
                            techniqueEntityDatas.Add(techniqueEntityData);
                        }
                        taskBoardListBTList.TechniqueEntityDatas = techniqueEntityDatas;
                        //部套名称
                        taskBoardListBTList.Name = bTnode.NodeName;
                        taskBoardListBTList.TaskHour = techniqueEntityDatas.Select(d => d.TaskHour).Sum().ToString() + "/" + techniqueEntityDatas.Select(d => d.CompleteHour).Sum().ToString();
                        taskBoardListBTList.TaskCount = techniqueEntityDatas.Select(d => d.CompleteCount).Sum().ToString() + "/" + techniqueEntityDatas.Select(d => d.TaskCount).Sum().ToString();
                    }
                    if (bopDesc.WorkingHourStatus == "1")//工步任务
                    {
                        foreach (var item in node)
                        {
                            TechniqueEntityData techniqueEntityData = new TechniqueEntityData();
                            var tech = _techniqueEntityRepository.FirstOrDefault(s => s.Id == item.TechniqueEntityId);
                            if (tech == null)
                            {
                                List<StatisticsHour> hours = new List<StatisticsHour>();
                                //var techList = node.Select(d => d.TechniqueEntityId);

                                var totalWork = from cc in _workStepEntityRepository.GetAll()
                                                where cc.TechniqueEntityId == tech.Id
                                                select new StatisticsHour { Id = cc.Id, Hour = cc.WorkStepWorking };
                                var workSteps = (from cc in _processesEntityRepository.GetAll()
                                                 join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                                 join pp in _workStepEntityRepository.GetAll() on cc.Id equals pp.ProcessesEntityId
                                                 where ff.ProductingStatus == ProductingStatus.已完成 && cc.TechniqueEntityId == tech.Id
                                                 select new StatisticsHour { Id = pp.Id, Hour = pp.WorkStepWorking }).ToList();
                                var workFinish = (from cc in totalWork
                                                  join ff in _productionSchedulerRepository.GetAll() on cc.Id equals ff.NodeId
                                                  where ff.ProductingStatus == ProductingStatus.已完成
                                                  select new StatisticsHour { Id = cc.Id, Hour = cc.Hour }).ToList();
                                if (workSteps.Count > 0)
                                {
                                    hours.AddRange(workSteps);
                                }
                                if (workFinish.Count > 0)
                                {
                                    hours.AddRange(workFinish);
                                }

                                if (hours.Count() > 0)
                                {
                                    //完成数量
                                    techniqueEntityData.CompleteCount = hours.Count;
                                    //任务数量
                                    techniqueEntityData.TaskCount = totalWork.Count();
                                    //完成工时
                                    techniqueEntityData.CompleteHour = (int)hours.Sum(d => d.Hour);
                                    //任务工时
                                    techniqueEntityData.TaskHour = (int)totalWork.Sum(d => d.Hour);
                                }
                                else
                                {
                                    //完成数量
                                    techniqueEntityData.CompleteCount = 0;
                                    //任务数量
                                    techniqueEntityData.TaskCount = totalWork.Count();
                                    //完成工时
                                    techniqueEntityData.CompleteHour = 0;
                                    //任务工时
                                    techniqueEntityData.TaskHour = (int)totalWork.Sum(d => d.Hour);
                                }
                                //规程图号
                                techniqueEntityData.DrawingNo = tech.TechniqueNumber;
                                //规程名称
                                techniqueEntityData.Name = tech.TechniqueName;
                                //状态
                                if (techniqueEntityData.TaskCount == techniqueEntityData.CompleteCount && techniqueEntityData.TaskCount > 0)
                                {
                                    techniqueEntityData.State = "已完成";
                                }
                                if (techniqueEntityData.TaskCount > techniqueEntityData.CompleteCount && techniqueEntityData.TaskCount > 0)
                                {
                                    techniqueEntityData.State = "生产中";
                                }
                                if (techniqueEntityData.TaskCount == 0)
                                {
                                    techniqueEntityData.State = "未生产";
                                }
                                techniqueEntityDatas.Add(techniqueEntityData);
                            }
                        }
                        taskBoardListBTList.TechniqueEntityDatas = techniqueEntityDatas;
                        //部套名称
                        taskBoardListBTList.Name = bTnode.NodeName;
                        taskBoardListBTList.BTId = btid;
                        taskBoardListBTList.TaskHour = techniqueEntityDatas.Select(d => d.CompleteHour).Sum().ToString() + "/" + techniqueEntityDatas.Select(d => d.TaskHour).Sum().ToString();
                        taskBoardListBTList.TaskCount = techniqueEntityDatas.Select(d => d.CompleteCount).Sum().ToString() + "/" + techniqueEntityDatas.Select(d => d.TaskCount).Sum().ToString();
                    }
                }
            }
            return taskBoardListBTList;
        }
        private class StatisticsHour
        {
            public Guid Id { get; set; }

            public decimal Hour { get; set; }
        }
    }
}
